/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of LINAL (LINear ALgebra)
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#include "internal_test.hxx"

int main(int argc, char **argv) {
  FLA_Init();
  linal::Flat_    A,  B, norm;
  FLA_Obj p;

  double t, t_block, t_unblock;

  int m = N;
  int datatype = TEST_DATATYPE;
  
  A.create   (datatype, m, m);
  B.create   (datatype, m, m);
  norm.create(datatype, 1, 1);

  FLA_Obj_create_without_buffer( FLA_INT, m, 1, &p );

  FLA_Random_matrix(~A);
  FLA_Copy( ~A, ~B );

  int p_buf[N];
  for (int i=0;i<m;++i) 
    p_buf[i] = (N - i) - 1;

  FLA_Obj_attach_buffer( p_buf, 0, 0, &p );
  FLA_Obj_show( "====", p, " %d ", "====" );
  A.disp("A original");
  linal::apply_pivots_ln_internal( p, ~A );
  A.disp("A after pivot ln");
  linal::apply_pivots_rt_internal( p, ~A );
  A.disp("A after pivot rt");
  linal::apply_pivots_lt_internal( p, ~A );
  A.disp("A after pivot lt");
  linal::apply_pivots_rn_internal( p, ~A );
  A.disp("A after pivot rn");

  FLA_Axpy(FLA_MINUS_ONE, ~A, ~B);
  FLA_Norm1( ~B, ~norm);

  float  norm_f = (float)norm(0,0);
  double norm_d = (double)norm(0,0);

  int rval;

  printf("- TEST::");
  for (int i=0;i<argc;++i)
    printf(" %s ", argv[i] );
  printf("\n");

  switch (datatype) {
  case LINAL_SINGLE_REAL:
    if (norm_f < LINAL_ERROR_TOL) {
      printf("PASS::Norm :: %E \n", norm_f);   rval = 0;
    } else {
      printf("FAIL::Norm :: %E \n", norm_f);   rval = -1;
    }
    break;
  case LINAL_DOUBLE_REAL:
    if (norm_d < LINAL_ERROR_TOL) {
      printf("PASS::Norm :: %E \n", norm_d);   rval = 0;
    } else {
      printf("FAIL::Norm :: %E \n", norm_d);   rval = -1;
    }
    break;
  }

  
  FLA_Obj_free_without_buffer( &p );

  norm.free();
  B.free(); 
  A.free(); 

  FLA_Finalize();
  return 0;
}



